package com.qiqidream.admin.common.response;

import com.qiqidream.admin.common.exception.BaseException;
import com.qiqidream.admin.monitor.model.entity.ErrorInfo;
import com.qiqidream.admin.monitor.service.ErrorService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import java.net.BindException;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;

/**
 * 异常处理器
 * @author QiQiDream
 * @since 2019/12/7 16:25
 */
@ControllerAdvice(annotations = BaseResponse.class)
@ResponseBody
@Slf4j
public class ExceptionHandlerAdvice {
    @Resource
    ErrorService errorService;

    /**
     * 处理未捕获的Exception
     * @param e 异常
     * @return 统一响应体
     */
    @ExceptionHandler(Exception.class)
    public ResponseResult handleException(Exception e){
        saveError(e);
        return ResponseResult.failed(ResponseCode.SERVICE_ERROR);
    }

    /**
     * 处理校验错误
     * @param e 异常
     * @return 统一响应体
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseResult checkRequest(MethodArgumentNotValidException e) {
        saveError(e);
        return ResponseResult.failed(Objects.requireNonNull(e.getBindingResult().getFieldError()).getDefaultMessage());
    }


    /**
     * 处理未捕获的RuntimeException
     * @param e 运行时异常
     * @return 统一响应体
     */
    @ExceptionHandler(RuntimeException.class)
    public ResponseResult handleRuntimeException(RuntimeException e){
        saveError(e);
        return ResponseResult.failed(ResponseCode.SERVICE_ERROR);
    }

    /**
     * 处理业务异常BaseException
     * @param e 业务异常
     * @return 统一响应体
     */
    @ExceptionHandler(BaseException.class)
    public ResponseResult handleBaseException(BaseException e){
        saveError(e);
        ResponseCode code = e.getCode();
        return ResponseResult.failed(code);
    }

    private void saveError(Exception e){
        log.error(e.getMessage(),e);

        ErrorInfo errorInfo = new ErrorInfo();
        errorInfo.setCreateDate(new Date().toLocaleString());
//        errorInfo.setErrorName(e.getClass().getName());
//        errorInfo.setMessage(e.getMessage());
        errorInfo.setDescription(e.toString());
        errorService.saveError(errorInfo);
    }
}
